package com.elitel.frame.base.service.strategy.service;

import com.elitel.frame.base.service.BaseQueryfieldService;
import com.elitel.frame.base.service.BaseShowfieldService;
import com.elitel.frame.base.service.CfgExtendService;
import com.elitel.frame.base.service.CfgTableService;
import com.elitel.frame.main.dao.AcServiceFilterFieldMapper;
import com.elitel.frame.main.entity.AcServiceFilterField;
import com.elitel.frame.main.entity.enums.BuildServiceEnum;
import com.elitel.frame.main.entity.ext.PrjServiceExt;
import com.elitel.frame.main.entity.vo.BaseQueryFieldVo;
import com.elitel.frame.main.entity.vo.BaseShowfieldVo;
import com.elitel.frame.main.entity.vo.ServiceConfig;
import com.elitel.frame.main.entity.vo.SingleTableInfoVo;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;
import org.springframework.util.ObjectUtils;

import javax.annotation.Resource;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * 单表服务策略
 *
 * @author xqh
 * @date 2025/02/07
 */
@Component
@Slf4j
public class SingleTableServerStrategy extends BuildServiceStrategy {

    @Resource
    private AcServiceFilterFieldMapper acServiceFilterFieldMapper;


    @Resource
    private CfgExtendService cfgExtendService;

    @Resource
    private CfgTableService cfgTableService;
    @Resource
    private BaseQueryfieldService baseQueryfieldService;

    @Resource
    private BaseShowfieldService baseShowfieldService;

    /**
     * 获取策略
     *
     * @return 策略枚举
     */
    protected BuildServiceEnum getTypeEnum() {
        return BuildServiceEnum.singleTableServer;
    }

    @Override
    public List<ServiceConfig> buildServiceModel(List<PrjServiceExt> prjServiceExtList) {

        // 收集所有需要处理的serviceId
        List<String> serviceGuids = prjServiceExtList.stream()
                .map(PrjServiceExt::getGuid)
                .collect(Collectors.toList());
        List<String> serviceCodes = prjServiceExtList.stream()
                .map(PrjServiceExt::getServicecode)
                .collect(Collectors.toList());
        //查询过滤字段
        List<AcServiceFilterField> acServiceFilterFieldList =
                acServiceFilterFieldMapper.selectByGuids(serviceGuids);
        Map<String, List<AcServiceFilterField>> acServiceFilterFieldMap = new HashMap<>();
        if (CollectionUtils.isNotEmpty(acServiceFilterFieldList)) {
            acServiceFilterFieldMap = acServiceFilterFieldList.stream()
                    .collect(Collectors.groupingBy(AcServiceFilterField::getServiceId));
        }
        // 批量查询CfgExtend cfgDb cfgTable
        List<SingleTableInfoVo> singleTableInfoVos =
                cfgExtendService.selectByServiceCodes(serviceCodes);

        Map<String, SingleTableInfoVo> singleTableInfoVosMap = singleTableInfoVos.stream()
                .collect(Collectors.toMap(SingleTableInfoVo::getServiceCode, Function.identity()));


        // 查询字段 base_queryfield
        List<BaseQueryFieldVo> baseQueryfieldList = baseQueryfieldService.selectByServiceCodes(serviceCodes);
        Map<String, List<BaseQueryFieldVo>> baseQueryFieldListMap =
                baseQueryfieldList.stream().collect(Collectors.groupingBy(BaseQueryFieldVo::getServiceId));

        //显示字段 base_showfield
        List<BaseShowfieldVo> baseShowfieldExts = baseShowfieldService.selectByServiceCodes(serviceCodes);
        Map<String, List<BaseShowfieldVo>> baseShowfieldListMap = baseShowfieldExts.stream().collect(Collectors.groupingBy(BaseShowfieldVo::getServiceid));


        List<ServiceConfig> serviceList = new ArrayList<>();

        for (PrjServiceExt service : prjServiceExtList) {

            ServiceConfig serviceConfig = getBaseServiceMap(service);
            String guid = service.getGuid();
            String servicecode = service.getServicecode();

            SingleTableInfoVo serviceInfoVo = singleTableInfoVosMap.get(servicecode);

            serviceConfig.setPageFlag(serviceInfoVo.getIspagination());

            List<AcServiceFilterField> acServiceFilterFields = acServiceFilterFieldMap.get(guid);

            buildAccessRule(acServiceFilterFields, serviceConfig);


            ServiceConfig.ExtInfo extInfo = new ServiceConfig.ExtInfo();

            ServiceConfig.DataSource dataSource = new ServiceConfig.DataSource();
            dataSource.setType(serviceInfoVo.getDbVersion());
            dataSource.setUrl(serviceInfoVo.getDbUrl());
            dataSource.setUser(serviceInfoVo.getDbUser());
            dataSource.setPassword(serviceInfoVo.getDbPwd());

            List<BaseShowfieldVo> baseShowfieldVos = baseShowfieldListMap.get(servicecode);
            List<String> fields = baseShowfieldVos.stream()
                    .map(BaseShowfieldVo::getDfname)
                    .collect(Collectors.toList());

            List<BaseQueryFieldVo> queryfields = Optional.ofNullable(baseQueryFieldListMap.get(servicecode)).orElse(Collections.emptyList());
            String myBatisOgnl = MyBatisOgnlGenerator
                    .generateMyBatisOgnl(fields, queryfields, serviceInfoVo.getDtName());
            extInfo.setSqlText(myBatisOgnl);

            extInfo.setDataSource(dataSource);

            serviceConfig.setExtInfo(extInfo);

            //设置查询参数
            List<ServiceConfig.QueryParam> queryParamList = new ArrayList<>();

            List<BaseQueryFieldVo> baseQueryfields = baseQueryFieldListMap.get(servicecode);
            if (CollectionUtils.isNotEmpty(baseQueryfields)) {
                for (BaseQueryFieldVo baseQueryfield : baseQueryfields) {
                    ServiceConfig.QueryParam queryParam = new ServiceConfig.QueryParam();
                    queryParam.setFieldCode(baseQueryfield.getParameterCode());
                    if (StringUtils.isNotEmpty(baseQueryfield.getRequiredFlag())) {
                        queryParam.setRequiredFlag(Integer.valueOf(baseQueryfield.getRequiredFlag()));
                    } else {
                        queryParam.setRequiredFlag(0);
                    }
                    queryParamList.add(queryParam);
                }
            }


            serviceConfig.setQueryParam(queryParamList);

            serviceList.add(serviceConfig);
        }
        return serviceList;

    }


    private void buildAccessRule(List<AcServiceFilterField> acServiceFilterFields, ServiceConfig serviceConfig) {
        ServiceConfig.AccessRule accessRule = new ServiceConfig.AccessRule();
        accessRule.setEnable(ObjectUtils.isEmpty(acServiceFilterFields) ? 0 : 1);
        if (!ObjectUtils.isEmpty(acServiceFilterFields)) {
            //过滤出第一个acServiceFilterFields中是否有filterType为STCD的数据
            Optional<AcServiceFilterField> stcd = acServiceFilterFields.stream()
                    .filter(item -> "STCD".equals(item.getFilterType()))
                    .findFirst();
            Optional<AcServiceFilterField> tm = acServiceFilterFields.stream()
                    .filter(item -> "TM".equals(item.getFilterType()))
                    .findFirst();
            if (stcd.isPresent()) {
                // 存在STCD数据
                AcServiceFilterField acServiceFilterField = stcd.get();
                accessRule.setStcdField(acServiceFilterField.getFieldCode());
            } else {
                // 不存在STCD数据
                accessRule.setStcdField("");
            }
            if (tm.isPresent()) {
                AcServiceFilterField acServiceFilterField = tm.get();
                accessRule.setTmField(acServiceFilterField.getFieldCode());
            } else {
                accessRule.setTmField("");
            }
        }
        serviceConfig.setAccessRule(accessRule);
    }


}
